package main

import (
	"fmt"
	"log"
	"time"

	modbus "gitee.com/barryzxy/gomodbus"
)

func main() {
	fmt.Println("=== 网关协议客户端API演示 ===")

	// 创建TCP客户端，连接到网关设备
	provider := modbus.NewTCPClientProvider("127.0.0.1:5020",
		modbus.WithTCPTimeout(3*time.Second),
		modbus.WithEnableLogger())
	client := modbus.NewClient(provider)

	fmt.Println("✓ 客户端创建成功（注意：此示例不实际连接设备）")

	// 演示各种客户端API功能
	demonstrateGatewayAPIs(client)
}

func demonstrateGatewayAPIs(client modbus.Client) {
	// 1. 读取变送器当前数据 (Unit ID = 5)
	fmt.Println("\n1. 读取变送器当前数据:")
	currentData, err := client.GatewayReadCurrentData(5)
	if err != nil {
		fmt.Printf("   错误: %v\n", err)
	} else {
		fmt.Printf("   压力: %s\n", currentData.GetPressureString())
		fmt.Printf("   电池电量: %d%%\n", currentData.BatteryLevel)
		fmt.Printf("   连接状态: %s\n", modbus.GetConnectionStatusName(currentData.ConnectionStatus))
		fmt.Printf("   信号强度: %s\n", currentData.GetSignalStrengthDescription())
		fmt.Printf("   采集时间: %s\n", currentData.GetTimeString())
		fmt.Printf("   设备状态: %v\n", currentData.IsDeviceOnline())
	}

	// 2. 数据对齐 - 获取合法的时间戳
	fmt.Println("\n2. 数据对齐 - 获取最新时间戳:")
	alignedTimestamp, err := client.GatewayReadDataRecordsAlign(5, 0)
	if err != nil {
		fmt.Printf("   错误: %v\n", err)
		return
	}
	fmt.Printf("   对齐时间戳: %d (%s)\n", alignedTimestamp,
		time.Unix(int64(alignedTimestamp), 0).Format("2006-01-02 15:04:05"))

	// 3. 批量读取历史数据
	fmt.Println("\n3. 批量读取32条历史数据:")
	records, err := client.GatewayReadDataRecords(5, alignedTimestamp)
	if err != nil {
		fmt.Printf("   错误: %v\n", err)
	} else {
		fmt.Printf("   成功读取 %d 条记录\n", len(records))
		// 显示前3条记录作为示例
		for i := 0; i < 3 && i < len(records); i++ {
			record := records[i]
			fmt.Printf("   记录 %d: %s, 电量:%d%%, 时间:%s\n",
				i+1, record.GetPressureString(), record.BatteryLevel, record.GetTimeString())
		}
		if len(records) > 3 {
			fmt.Printf("   ... 还有 %d 条记录\n", len(records)-3)
		}
	}

	// 4. 修改变送器参数 - 设置压力单位为bar
	fmt.Println("\n4. 修改变送器参数 - 设置压力单位为bar:")
	err = client.GatewayWriteSubDevParam(5, modbus.SubDevParamPressureUnit, modbus.PressureUnitBar)
	if err != nil {
		fmt.Printf("   错误: %v\n", err)
	} else {
		fmt.Printf("   ✓ 成功设置压力单位为bar\n")
	}

	// 5. 修改变送器参数 - 设置数据上报间隔为60秒
	fmt.Println("\n5. 修改变送器参数 - 设置数据上报间隔为60秒:")
	err = client.GatewayWriteSubDevParam(5, modbus.SubDevParamDataReportInterval, 60)
	if err != nil {
		fmt.Printf("   错误: %v\n", err)
	} else {
		fmt.Printf("   ✓ 成功设置数据上报间隔为60秒\n")
	}

	// 6. 修改网关参数 - 设置RS485波特率 (Unit ID = 65)
	fmt.Println("\n6. 修改网关参数 - 设置RS485波特率为115200:")
	err = client.GatewayWriteGatewayParam(65, modbus.GatewayParamRS485Baudrate, 115200)
	if err != nil {
		fmt.Printf("   错误: %v\n", err)
	} else {
		fmt.Printf("   ✓ 成功设置RS485波特率为115200bps\n")
	}

	// 7. 修改网关参数 - 更新系统时间
	fmt.Println("\n7. 修改网关参数 - 更新系统时间:")
	currentTime := uint32(time.Now().Unix())
	err = client.GatewayWriteGatewayParam(65, modbus.GatewayParamTime, currentTime)
	if err != nil {
		fmt.Printf("   错误: %v\n", err)
	} else {
		fmt.Printf("   ✓ 成功更新系统时间为: %s\n",
			time.Unix(int64(currentTime), 0).Format("2006-01-02 15:04:05"))
	}

	// 8. 演示错误处理 - 尝试向错误的Unit ID写参数
	fmt.Println("\n8. 演示错误处理 - 向无效Unit ID写参数:")
	err = client.GatewayWriteSubDevParam(100, modbus.SubDevParamPressureUnit, modbus.PressureUnitKPa)
	if err != nil {
		fmt.Printf("   预期错误: %v\n", err)
	}
}

// 数据转换工具演示
func demonstrateDataConversion() {
	fmt.Println("\n=== 数据转换工具演示 ===")

	// 创建示例数据记录
	record := &modbus.DataRecord{
		Pressure:         25.8,
		PressureUnit:     modbus.PressureUnitKPa,
		BatteryLevel:     88,
		ConnectionStatus: 1,
		SignalLevel:      4,
		Timestamp:        uint32(time.Now().Unix()),
	}

	fmt.Println("\n原始数据记录:")
	fmt.Printf("压力: %s\n", record.GetPressureString())
	fmt.Printf("电池电量: %d%%\n", record.BatteryLevel)
	fmt.Printf("连接状态: %s\n", modbus.GetConnectionStatusName(record.ConnectionStatus))
	fmt.Printf("信号强度: %s\n", record.GetSignalStrengthDescription())
	fmt.Printf("采集时间: %s\n", record.GetTimeString())
	fmt.Printf("设备在线: %v\n", record.IsDeviceOnline())

	// 转换为字节数组
	bytes := record.ToBytes()
	fmt.Printf("\n字节数组 (16字节): %x\n", bytes)

	// 从字节数组还原
	restored, err := modbus.NewDataRecordFromBytes(bytes)
	if err != nil {
		fmt.Printf("还原失败: %v\n", err)
		return
	}

	fmt.Println("\n还原后的数据记录:")
	fmt.Printf("压力: %s\n", restored.GetPressureString())
	fmt.Printf("电池电量: %d%%\n", restored.BatteryLevel)
	fmt.Printf("连接状态: %s\n", modbus.GetConnectionStatusName(restored.ConnectionStatus))
	fmt.Printf("信号强度: %s\n", restored.GetSignalStrengthDescription())
	fmt.Printf("采集时间: %s\n", restored.GetTimeString())
}

// 参数配置示例
func demonstrateParameterConfiguration() {
	fmt.Println("\n=== 参数配置示例 ===")

	// 假设客户端已连接
	fmt.Println("\n支持的变送器参数配置:")
	paramExamples := map[string]struct {
		addr  uint16
		value uint32
		desc  string
	}{
		"压力单位":  {modbus.SubDevParamPressureUnit, modbus.PressureUnitMPa, "设置为MPa"},
		"显示小数位": {modbus.SubDevParamLCDDecimalPlaces, 3, "显示3位小数"},
		"变送器地址": {modbus.SubDevParamTransmitterAddr, 10, "设置为10号"},
		"显示语言":  {modbus.SubDevParamLanguage, 1, "设置为英文"},
		"液晶旋转":  {modbus.SubDevParamLCDRotation, 2, "旋转180度"},
		"背光时间":  {modbus.SubDevParamBacklightTime, 3, "60秒"},
		"操作密码":  {modbus.SubDevParamLCDPassword, 1234, "设置密码1234"},
		"上报间隔":  {modbus.SubDevParamDataReportInterval, 300, "5分钟上报"},
	}

	for name, param := range paramExamples {
		fmt.Printf("- %s: 地址=0x%04X, 值=%d (%s)\n",
			name, param.addr, param.value, param.desc)
	}

	fmt.Println("\n支持的网关参数配置:")
	gatewayExamples := map[string]struct {
		addr  uint16
		value uint32
		desc  string
	}{
		"系统时间":     {modbus.GatewayParamTime, uint32(time.Now().Unix()), "当前时间"},
		"RS485波特率": {modbus.GatewayParamRS485Baudrate, 9600, "9600bps"},
		"RS485地址":  {modbus.GatewayParamRS485Address, 66, "66号网关"},
		"背光时间":     {modbus.GatewayParamBacklightTime, 1, "30秒"},
	}

	for name, param := range gatewayExamples {
		fmt.Printf("- %s: 地址=0x%04X, 值=%d (%s)\n",
			name, param.addr, param.value, param.desc)
	}
}

func init() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
}
